package com.dubito.composenote.ui.screen

import android.net.Uri
import android.widget.Toast
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.material.TextFieldDefaults
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.NavGraph.Companion.findStartDestination
import coil.compose.AsyncImage
import com.dubito.composenote.Constants
import com.dubito.composenote.R
import com.dubito.composenote.model.Note
import com.dubito.composenote.model.getDay
import com.dubito.composenote.ui.composable.DeleteDialog
import com.dubito.composenote.ui.composable.GenericAppBar
import com.dubito.composenote.ui.composable.NotesFloatingActionButton

/**
 * author: LiLiang
 * createTime: 2022/10/6-19:37
 * remark:
 **/
@Composable
fun NoteScreen(
    navController: NavController,
    viewModel: NoteViewModel
) {
    val deleteText = remember {
        mutableStateOf("")
    }
    val noteQuery = remember {
        mutableStateOf("")
    }
    val noteToDelete = remember {
        mutableStateOf(listOf<Note>())
    }
    val openDialog = remember {
        mutableStateOf(false)
    }
    val context = LocalContext.current

    val notes = viewModel.notes.collectAsState(initial = listOf())

    Surface(modifier = Modifier.fillMaxSize()) {
        Scaffold(
            topBar = {
                GenericAppBar(
                    title = stringResource(R.string.home),
                    onIconClick = {
                        if (notes.value.isNotEmpty()) {
                            openDialog.value = true
                            deleteText.value = "你确定要删除所有的便签?"
                            noteToDelete.value = notes.value
                        } else {
                            Toast.makeText(context, "找不到内容", Toast.LENGTH_SHORT).show()
                        }
                    },
                    icon = {
                        Icon(
                            imageVector = Icons.Default.Delete,
                            contentDescription = stringResource(R.string.delete),
                            tint = Color.Black
                        )
                    },
                    iconState = remember {
                        mutableStateOf(true)
                    }
                )
            },
            floatingActionButton = {
                NotesFloatingActionButton(
                    contentDescription = stringResource(R.string.add),
                    action = {
                        navController.navigate(Constants.NOTE_CREATE) {
                            popUpTo(navController.graph.findStartDestination().id) {
                                saveState = true
                            }
                            launchSingleTop = true
                            restoreState = true
                        }
                    },
                    icon = Icons.Filled.Add
                )
            }
        ) { paddingValues ->
            Column(modifier = Modifier.padding(paddingValues)) {
                SearchBar(query = noteQuery)
                NoteItems(
                    notes = notes.value,
                    openDialog = openDialog,
                    query = noteQuery,
                    deleteText = deleteText,
                    navController = navController,
                    notesToDelete = noteToDelete
                )
                DeleteDialog(
                    openDialog = openDialog,
                    text = deleteText,
                    action = {
                        noteToDelete.value.forEach {
                            viewModel.deleteNote(note = it)
                        }
                    },
                    noteToDelete = noteToDelete
                )
            }
        }
    }
}


@Composable
fun SearchBar(query: MutableState<String>) {
    Column(modifier = Modifier.padding(top = 12.dp, start = 12.dp, end = 12.dp, bottom = 0.dp)) {
        TextField(
            value = query.value,
            onValueChange = { query.value = it },
            placeholder = { Text(text = "搜索...") },
            modifier = Modifier
                .background(Color.White)
                .clip(RoundedCornerShape(12.dp))
                .fillMaxWidth(),
            colors = TextFieldDefaults.textFieldColors(textColor = Color.Black),
            trailingIcon = {
                AnimatedVisibility(
                    visible = query.value.isNotBlank(),
                    enter = fadeIn(),
                    exit = fadeOut()
                ) {
                    IconButton(onClick = { query.value = "" }) {
                        Icon(
                            imageVector = Icons.Default.Close,
                            contentDescription = stringResource(R.string.search)
                        )
                    }
                }
            }
        )
    }
}

@Composable
fun NoteItems(
    notes: List<Note>,
    openDialog: MutableState<Boolean>,
    query: MutableState<String>,
    deleteText: MutableState<String>,
    navController: NavController,
    notesToDelete: MutableState<List<Note>>
) {
    var previousHeader = ""
    LazyColumn(
        contentPadding = PaddingValues(12.dp),
//        modifier = Modifier.background(MaterialTheme.colors.primary)
    ) {
        val queriedNotes = if (query.value.isEmpty()) {
            notes
        } else {
            notes.filter { it.note.contains(query.value) || it.title.contains(query.value) }
        }
        itemsIndexed(queriedNotes) { index, note ->
            if (note.getDay() != previousHeader) {
                Column(
                    modifier = Modifier
                        .padding(6.dp)
                        .fillMaxWidth()
                ) {
                    Text(text = note.getDay(), color = Color.Black)
                }
                Spacer(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(6.dp)
                )
            }
            NoteItem(
                note,
                openDialog,
                deleteText,
                notesToDelete,
                navController,
                if (index % 2 == 0) Color.Yellow else Color.LightGray
            )
            Spacer(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(12.dp)
            )
            previousHeader = note.getDay()
        }
    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun NoteItem(
    note: Note,
    openDialog: MutableState<Boolean>,
    deleteText: MutableState<String>,
    notesToDelete: MutableState<List<Note>>,
    navController: NavController,
    background: Color
) {
    Box(
        modifier = Modifier
            .height(120.dp)
            .clip(RoundedCornerShape(12.dp))
    ) {
        Column(
            modifier = Modifier
                .background(background)
                .height(120.dp)
                .combinedClickable(
                    interactionSource = remember {
                        MutableInteractionSource()
                    },
                    indication = rememberRipple(bounded = false),
                    onClick = {
                        navController.navigate(
                            Constants.noteDetailNavigation(
                                noteId = note.id ?: 0
                            )
                        )
                    },
                    onLongClick = {
                        openDialog.value = true
                        deleteText.value = "你确定要删除吗?"
                        notesToDelete.value = mutableListOf(note)
                    }
                )
        ) {
            Row {
                if (note.imageUri != null && note.imageUri.isNotBlank()) {
                    AsyncImage(
                        model = Uri.parse(note.imageUri),
                        contentDescription = "",
                        modifier = Modifier.fillMaxWidth(0.3f)
                    )
                }
                Column {
                    Text(
                        text = note.title,
                        color = Color.Black,
                        fontWeight = FontWeight.Bold,
                        modifier = Modifier.padding(horizontal = 12.dp)
                    )
                    Text(
                        text = note.note,
                        color = Color.Black,
                        maxLines = 3,
                        modifier = Modifier.padding(horizontal = 12.dp)
                    )
                    Text(
                        text = note.dateUpdated,
                        color = Color.Black,
                        modifier = Modifier.padding(horizontal = 12.dp)
                    )
                }
            }
        }
    }
}


